package it.traveldreamWeb.customer;


import it.traveldream.beans.AccountFactoryInterface;
import it.traveldream.beans.BookingManagerInterface;
import it.traveldream.dto.ExcursionDTO;
import it.traveldream.dto.HotelDTO;
import it.traveldream.dto.HotelDTO.HotelRoomType;
import it.traveldream.dto.ReservationDTO;
import it.traveldream.dto.TPDTO;
import it.traveldream.dto.TransportMeanDTO;
import it.traveldream.dto.UserDTO;
import it.traveldream.exceptions.InvalidReservationException;
import it.traveldream.exceptions.ProductNotFoundException;
import it.traveldream.exceptions.ProductSoldOutException;
import it.traveldreamWeb.shared.HotelRoom;

import java.util.Calendar;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.ejb.EJB;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.SessionScoped;

@ManagedBean(name="reservationBean")
@SessionScoped
public class ReservationBean {
	
	private UserDTO customer;
	
	private TPDTO selectedTP;
	private TransportMeanDTO selectedMean;
	private HotelDTO selectedHotel;
	private List<HotelRoom> selectedRooms;
	private List<ExcursionDTO> selectedExs;
	private int travellers;
	private int duration;
	private Date leavingDate;
	
	private String successMessage;
	private String invitationLink;
	
	@EJB
	private BookingManagerInterface bookingManager;
	@EJB
	private AccountFactoryInterface userManager;
	
	public ReservationBean(){
	}
	
	public void initCustomer(){
		this.customer = this.userManager.getCurrentCustomer();
	}
	
	public ReservationDTO bookTravel(boolean discount) throws ProductNotFoundException, ProductSoldOutException, InvalidReservationException{
		Calendar cal = Calendar.getInstance();
		cal.setTime(this.leavingDate);
		cal.add(Calendar.DATE, this.duration);
		Map<HotelRoomType, Integer> rooms = new HashMap<>();
	
		for (HotelRoom r : this.selectedRooms){
			if (r.getSelectedRooms() == null)
				rooms.put(r.getType(), 0);
			else
				rooms.put(r.getType(), r.getSelectedRooms());
		}
		
		if (! this.bookingManager.checkAvailability(this.selectedMean, 
				this.selectedHotel, this.leavingDate, cal.getTime(), this.travellers, rooms))
			throw new ProductSoldOutException();
		
		ReservationDTO r = new ReservationDTO();
		r.setEndDate(cal.getTime());
		r.setExcursions(this.selectedExs);
		r.setHotel(this.selectedHotel);
		r.setHotelRooms(rooms);
		r.setLeavingDate(this.leavingDate);
		r.setMean(this.selectedMean);
		r.setTravellers(this.travellers);
		r = this.bookingManager.book(r, discount);
		return r;
	}

	public TransportMeanDTO getSelectedMean() {
		return this.selectedMean;
	}

	public void setSelectedMean(TransportMeanDTO selectedMean) {
		this.selectedMean = selectedMean;
	}

	public int getTravellers() {
		return this.travellers;
	}

	public void setTravellers(int travellers) {
		this.travellers = travellers;
	}

	public List<HotelRoom> getSelectedRooms() {
		return this.selectedRooms;
	}

	public void setSelectedRooms(List<HotelRoom> selectedRooms) {
		this.selectedRooms = selectedRooms;
	}

	public TPDTO getSelectedTP() {
		return this.selectedTP;
	}

	public void setSelectedTP(TPDTO selectedTP) {
		this.selectedTP = selectedTP;
	}

	public HotelDTO getSelectedHotel() {
		return this.selectedHotel;
	}

	public void setSelectedHotel(HotelDTO selectedHotel) {
		this.selectedHotel = selectedHotel;
	}

	public List<ExcursionDTO> getSelectedExs() {
		return this.selectedExs;
	}

	public void setSelectedExs(List<ExcursionDTO> selectedExs) {
		this.selectedExs = selectedExs;
	}

	public int getDuration() {
		return this.duration;
	}

	public void setDuration(int duration) {
		this.duration = duration;
	}

	public Date getLeavingDate() {
		return this.leavingDate;
	}

	public void setLeavingDate(Date leavingDate) {
		this.leavingDate = leavingDate;
	}
	
	public Date getEndDate() {
		if (this.leavingDate == null)
			return null;
		
		Calendar l = Calendar.getInstance();
		l.setTime(this.leavingDate);
		l.add(Calendar.DATE, this.duration);
		return l.getTime();
	}

	public UserDTO getCustomer() {
		return this.customer;
	}

	public void setCustomer(UserDTO customer) {
		this.customer = customer;
	}
	

	public String getSuccessMessage() {
		return this.successMessage;
	}

	public void setSuccessMessage(String successMessage) {
		this.successMessage = successMessage;
	}

	public String getInvitationLink() {
		return this.invitationLink;
	}

	public void setInvitationLink(String invitationLink) {
		this.invitationLink = invitationLink;
	}

	public void cleanSession() {
		this.selectedTP = null;
		this.selectedMean = null;
		this.selectedHotel = null;
		this.selectedRooms = null;
		this.selectedExs = null;
		this.travellers = 0;
		this.duration = 0;
		this.leavingDate = null;
		
		
	}
	
	public void cleanMessages(){
		this.successMessage = "";
		this.invitationLink = "";
	}
}
